package autoorder.zsxmlv.service;

import autoorder.zsxmlv.component.PushMsgComponent;
import autoorder.zsxmlv.enums.TaskEnum;
import autoorder.zsxmlv.mapper.WechatUserMapper;
import autoorder.zsxmlv.po.*;
import common.zsxmlv.vo.Result;
import common.zsxmlv.vo.im.Message;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author: ZSXM
 * @Description:
 * @Company: DingZheng
 * @Date: Create by 2018/6/9 21:16
 * @Version: 1.0
 * @Modify by:
 */
@Service
public class SeleniumService {

    @Bean
    public Message getMessageBean() {
        Message message = new Message();
        message.setAvatar("/zs/admin2/images/sys_head.png");
        message.setUsername("系统");
        message.setMine(false);
        message.setTimestamp(System.currentTimeMillis());
        message.setId("20000");
        message.setFromid("20000");
        message.setType("friend");
        return message;
    }

    @Resource
    private AccountService accountService;

    @Resource
    private GoodsService goodsService;

    @Resource
    private OrderService orderService;

    @Resource
    private TaskService taskService;

    @Resource
    private WechatUserMapper wechatUserMapper;


    /**
     * 处理核心方法
     * @param message
     */
    public void executeSendOrder(String message) {
        CopyOnWriteArraySet<WebSocket> webSocketSet = WebSocket.webSocketSet;
        Message messageBean = getMessageBean();
        if (message != null && message.trim().length() != 0) {
            /**
             * 1、转码JSON字符串为JSON对象
             * 2、根据JSON对象的code判断客户端请求类型
             * 3、根据请求类型做出相关的爬虫下单动作
             * 4、出现任何错误返回相关执行状态信息,以及相关错误信息
             */
            try {
                JSONObject jsonObject = JSONObject.fromObject(message);
                Integer code = (Integer) jsonObject.get("code");
                if (0 == code) {
                    Object data = jsonObject.get("data");
                    jsonObject = JSONObject.fromObject(data);
                    Integer accountId = (Integer) jsonObject.get("accountId");
                    Integer goodsId = (Integer) jsonObject.get("goodsId");
                    this.coreMethod(goodsId, accountId);
                } else {
                    messageBean.setMsg("暂不支持您自定义发送消息");
                    messageBean.setMsgType(2);
                }
                this.sendMsg(webSocketSet, messageBean);
            } catch (Exception e) {
                messageBean.setMsgType(2);
                messageBean.setContent(e.getMessage());
                this.sendMsg(webSocketSet, messageBean);
            }
        } else {
            /**
             * 接收消息错误
             * 广播消息,请求代码格式错误(弹窗形式)
             */
            messageBean.setMsg("暂不支持您自定义发送消息");
            messageBean.setMsgType(2);
            this.sendMsg(webSocketSet, messageBean);
        }
    }

    public void coreMethod(Integer goodsId, Integer accountId) {
        Message messageBean = this.getMessageBean();
        CopyOnWriteArraySet<WebSocket> webSocketSet = WebSocket.webSocketSet;
        Goods goods = goodsService.getGoodsById(goodsId);
        Account account = accountService.getById(accountId);
        String goodsUrl = "http://buy.ccb.com/products/pd_" + goods.getGoodsId() + ".jhtml";

        ChromeDriver chromeDriver = new ChromeDriver();
        try {
            chromeDriver.get(goodsUrl);
//            chromeDriver.manage().window().maximize();
//            chromeDriver.
            Thread.sleep(3000);
            chromeDriver.findElementById("buy_now_button").click();
            Thread.sleep(2000);
            chromeDriver.switchTo().frame("jbox-iframe");
            Thread.sleep(1500);
            chromeDriver.findElementById("custname").sendKeys(account.getCustname());
            chromeDriver.findElementById("custpwd").sendKeys(account.getCustpwd());
            Thread.sleep(1150);
            chromeDriver.findElementByName("sub").click();
            Thread.sleep(4500);
            System.out.println("确认同意 start");
            try {
                System.out.println("点击 确认");
                // 因善融商务部分功能升级优化，请您查阅并确认以下内容。 我已知悉并同意
                chromeDriver.findElementById("sure").click();
                Thread.sleep(1250);
            } catch (NoSuchElementException e) {
                System.out.println("没有找到元素啊");
                e.printStackTrace();
            }
            System.out.println("确认同意 end");
            chromeDriver.findElementByClassName("submit_btn").click();
            Thread.sleep(5000);
            WebElement qrcode2 = chromeDriver.findElementById("qrcode2");
            Thread.sleep(3800);

            String orderNum = chromeDriver.findElementById("detail")
                    .findElement(By.tagName("table")).findElement(By.tagName("tbody"))
                    .findElement(By.tagName("tr")).findElements(By.tagName("td"))
                    .get(1).getText();

            String payMoney = chromeDriver.findElementById("orderAmountId").getText();
            String src = qrcode2.getAttribute("src");
            if (src == null || "".equals(src)) {
                chromeDriver.navigate().refresh();
                Thread.sleep(3800);
                src = qrcode2.getAttribute("src");
            }

            Order order = new Order();
            order.setGoodsPrice(goods.getGoodsPrice());
            float price  = Float.parseFloat(payMoney);
            BigDecimal bigDecimal = BigDecimal.valueOf(price);
            order.setPayMoney(bigDecimal);
            order.setQrCode(src);
            order.setOrderNum(orderNum);
            order.setGoodsId(goods.getId());
            order.setUserId(account.getId());
            order.setTaskId(0);
            order.setIsOk(0);

            order.setGoodsName(goods.getGoodsName());
            order.setAccount(account.getCustname());
            order.setGoodsUrl(goodsUrl);
            Result insert = orderService.insert(order);

            messageBean.setContent("<h1 style='color: #03A9F4;margin-bottom: 10px;'>下单成功</h1>" +
                    "<p>订单序号：<span style='color: #f00;'>" + order.getId() + "</span></p>" +
                    "<p>订单编号：<span style='color: #7b756b;'>" + orderNum + "</span></p>" +
                    "<p>账号：<span style='color: #af6902;'>" + account.getCustname() + "</span></p>" +
                    "<p>商品：<a href='http://buy.ccb.com/products/pd_" + goods.getGoodsId() + ".jhtml' target='_blank' style='color: #34c0ff;'>" + goods.getGoodsName() + "</a></p>" +
                    "<p style='margin: 15px;'><img src='" + src + "' /></p>" +
                    "<p style='color: #f00;'>请尽快支付,避免过期</p>" +
                    "<p style=''><button class=\"layui-btn\" layadmin-event=\"sure_pay\" data-id='" + orderNum + "'>确认支付</button></p>"
            );
            this.sendMsg(webSocketSet, messageBean);

            List<WechatUser> isSetUserList = wechatUserMapper.getIsSetUserList();
            System.out.println("开始推送公众号模板消息");
            PushMsgComponent.pushTempletMessage(order, goods, account, isSetUserList);
            System.out.println("推送公众号模板消息完成");

            chromeDriver.quit();
//            int i = PushMsgComponent.pushTextCardMessage(order, goods, account);
//            if (i == 1) {
//                messageBean.setContent(TaskEnum.TASK_PUSU_SUCCESS.getMsg());
//                this.sendMsg(webSocketSet, messageBean);
//            } else {
//                messageBean.setContent(TaskEnum.TASK_PUSU_ERROR.getMsg());
//                sendMsg(webSocketSet, messageBean);
//            }
        } catch (Exception e) {
            messageBean.setContent("<p>账号：" + account.getCustname() + "</p>" +
                    "<p>商品：" + goods.getGoodsName() + "</p>" +
                    "<p>参考信息：" + e.getMessage() + "</p>");
            this.sendMsg(webSocketSet, messageBean);
            chromeDriver.quit();
        }
    }


    public void autoSendOrder(String code) {
        Result result = new Result();
        CopyOnWriteArraySet<WebSocket> webSocketSet = WebSocket.webSocketSet;
        Task task = null;
        List<Goods> goods = null;
        List<Account> accounts = null;
        if (code != null && code != "") {
            switch (code) {
                case "0":
                    // 0: 任务执行中 => 提示任务正在执行 请等待...
                    result.setCode(0);
                    result.setMsg("任务正在执行,请等待");
                    JSONObject object = JSONObject.fromObject(result);
                    sendMsg(webSocketSet, object);
                    task = taskService.selectByMaxId();
                    goods = goodsService.listAllGoodsByStatus(0);
                    accounts = accountService.listAllByStatus(0);
                    seleniumGetQrCode(goods, accounts, task);
                    break;
                case "1":
//                    // 1: 任务已完成 => 开始新的任务
//                    result = taskService.insert();
//                    if (result.getCode() == 0) {
//                        Task task = taskService.selectByMaxId();
//                        List<Goods> goods = goodsService.listAllGoodsByStatus(0);
//                        List<Account> accounts = accountService.listAllByStatus(0);
//                        seleniumGetQrCode(goods, accounts, task);
//                    }
//                    break;
                case "10002":
                    result = taskService.insert();
                    if (result.getCode() == 0) {
                        result.setCode(0);
                        result.setMsg("任务正在启动,请等待");
                        JSONObject object1 = JSONObject.fromObject(result);
                        sendMsg(webSocketSet, object1);
                        task = taskService.selectByMaxId();
                        goods = goodsService.listAllGoodsByStatus(0);
                        accounts = accountService.listAllByStatus(0);
                        seleniumGetQrCode(goods, accounts, task);
                    }
                    break;
                default:
                    result.setMsg(TaskEnum.TASK_ERROR.getMsg());
                    result.setCode(TaskEnum.TASK_ERROR.getCode());
                    JSONObject object1 = JSONObject.fromObject(result);
                    sendMsg(webSocketSet, object1);
                    break;
            }
        } else {
            // 服务器端收到的消息为空时，发生异常
            result.setMsg(TaskEnum.TASK_ERROR.getMsg());
            result.setCode(TaskEnum.TASK_ERROR.getCode());
            JSONObject object1 = JSONObject.fromObject(result);
            sendMsg(webSocketSet, object1);
        }
//        return result;
    }

    private Result seleniumGetQrCode(List<Goods> goodsList, List<Account> accountList, Task task) {
        Result result = new Result();

        if (goodsList != null && goodsList.size() > 0) {
            for (Goods goods : goodsList) {

                for (Account account : accountList) {

                    this.selenium(goods, account, task);

                }

            }
        } else {
            System.out.println("goodsList is null");
        }
        return result;
    }

    /**
     * 废弃
     * @param goods
     * @param account
     * @param task
     */
    private synchronized void selenium(Goods goods,Account account,Task task) {
        Result result = new Result();

        ChromeDriver chromeDriver = new ChromeDriver();
        CopyOnWriteArraySet<WebSocket> webSocketSet = WebSocket.webSocketSet;
        HashMap<String, Object> map = new HashMap<>();
        map.put("goods", goods);
        map.put("account", account);
        result.setData(map);
        try {
            /**
             * 流程：
             * 1、打开商品链接
             * 2、
             */
            chromeDriver.get("http://buy.ccb.com/products/pd_" + goods.getGoodsId() + ".jhtml");
            chromeDriver.manage().window().maximize();
            Thread.sleep(3000);
            chromeDriver.findElementById("buy_now_button").click();
            Thread.sleep(2000);
            chromeDriver.switchTo().frame("jbox-iframe");
            Thread.sleep(1500);
            chromeDriver.findElementById("custname").sendKeys(account.getCustname());
            chromeDriver.findElementById("custpwd").sendKeys(account.getCustpwd());
            Thread.sleep(1150);
            chromeDriver.findElementByName("sub").click();
            Thread.sleep(4500);
            try {
                // 因善融商务部分功能升级优化，请您查阅并确认以下内容。 我已知悉并同意
                chromeDriver.findElementById("sure").click();
                Thread.sleep(1250);
            } catch (NoSuchElementException e) {
                System.out.println("没有找到元素啊");
                e.printStackTrace();
            }
            chromeDriver.findElementByClassName("submit_btn").click();
            Thread.sleep(5000);
            WebElement qrcode2 = chromeDriver.findElementById("qrcode2");
            Thread.sleep(3800);
            String payMoney = chromeDriver.findElementById("orderAmountId").getText();
            String src = qrcode2.getAttribute("src");
            if (src == null || "".equals(src)) {
                chromeDriver.navigate().refresh();
                Thread.sleep(3800);
                src = qrcode2.getAttribute("src");
            }
            Order order = new Order();
            order.setGoodsPrice(goods.getGoodsPrice());
            float price  = Float.parseFloat(payMoney);
            BigDecimal bigDecimal = BigDecimal.valueOf(price);
            order.setPayMoney(bigDecimal);
            order.setQrCode(src);
            order.setGoodsId(goods.getId());
            order.setUserId(account.getId());
            order.setTaskId(task.getId());
            Result insert = orderService.insert(order);
            Integer successNum = task.getSuccessNum();
            task.setSuccessNum(successNum + 1);
            taskService.updateTask(task);
            result.setCode(TaskEnum.TASK_SELENIUM_SUCCESS.getCode());
            result.setMsg(TaskEnum.TASK_SELENIUM_SUCCESS.getMsg());
            JSONObject object = JSONObject.fromObject(result);
            sendMsg(webSocketSet, object);
//            int i = PushMsgComponent.pushTextCardMessage(order, goods, account);
            // 推送公众号消息
            System.out.println("开始推送公众号模板消息");
            PushMsgComponent.pushTempletMessage(order, goods, account, wechatUserMapper.getIsSetUserList());
            result.setCode(TaskEnum.TASK_PUSU_SUCCESS.getCode());
            result.setMsg(TaskEnum.TASK_PUSU_SUCCESS.getMsg());
            object = JSONObject.fromObject(result);
            sendMsg(webSocketSet, object);
            System.out.println("推送公众号模板消息完成");
//            if (i == 1) {
//                result.setCode(TaskEnum.TASK_PUSU_SUCCESS.getCode());
//                result.setMsg(TaskEnum.TASK_PUSU_SUCCESS.getMsg());
//                object = JSONObject.fromObject(result);
//                sendMsg(webSocketSet, object);
//            } else {
//                result.setCode(TaskEnum.TASK_PUSU_ERROR.getCode());
//                result.setMsg(TaskEnum.TASK_PUSU_ERROR.getMsg());
//                object = JSONObject.fromObject(result);
//                sendMsg(webSocketSet, object);
//            }
            chromeDriver.quit();
        } catch (Exception e) {
            /**
             * 当错误情况发生时：
             * 1、发送一个消息给前端显示
             * 2、更新任务表中的任务错误的商品id
             * 3、更新错误数量
             */
            Integer failNum = task.getFailNum();
            String errorIds = task.getErrorIds();
            task.setFailNum(failNum + 1);
            task.setErrorIds(goods.getId() + "," + errorIds);
            try {
                taskService.updateTask(task);
            } catch (Exception e1) {
                System.out.println("继续 别管我");
            }

            result.setCode(TaskEnum.TASK_SELENIUM_EXCEPTION.getCode());
            result.setMsg(TaskEnum.TASK_SELENIUM_EXCEPTION.getMsg());
            JSONObject object = JSONObject.fromObject(result);
            sendMsg(webSocketSet, object);
            System.out.println("获取 QRCODE ERROR...");
            e.printStackTrace();
            System.out.println("===============   error end  ===============");
            chromeDriver.quit();
        }
    }

    /**
     * 发送相关执行消息
     * @param webSocketSet
     * @param object 需要发送的消息 JSONObject
     */
    private void sendMsg(CopyOnWriteArraySet<WebSocket> webSocketSet, Object object) {
        JSONObject jsonObject = JSONObject.fromObject(object);
        for (WebSocket webSocket : webSocketSet) {
            try {
                webSocket.sendMessage(jsonObject.toString());
            } catch (IOException e1) {
                System.out.println("SeleniumService sendmessage exception");
                e1.printStackTrace();
            }
        }
    }

}
